/*
* Copyright 2012 Michael Chang, Tai-Lin Chu, Artin Menachekanian,
* Charles Rudolph, Eduard Sedakov, Suzanna Whiteside
*
* This file is part of ServerLibraryManager.
*
* ServerLibraryManager is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ServerLibraryManager is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with ServerLibraryManager. If not, see <http://www.gnu.org/licenses/>.
*/
package edu.ucla.loni.client;
import edu.ucla.loni.shared.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.http.client.URL;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.regexp.shared.SplitResult;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.AnimationEffect;
import com.smartgwt.client.types.KeyNames;
import com.smartgwt.client.types.ListGridComponent;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.util.ValueCallback;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.ResizedEvent;
import com.smartgwt.client.widgets.events.ResizedHandler;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Dialog;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.fields.events.KeyUpEvent;
import com.smartgwt.client.widgets.form.fields.events.KeyUpHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedEvent;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.MenuItemSeparator;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeNode;
import com.smartgwt.client.widgets.tree.events.NodeContextClickEvent;
import com.smartgwt.client.widgets.tree.events.NodeContextClickHandler;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class ServerLibraryManager implements EntryPoint {
////////////////////////////////////////////////////////////
// Private Variables
////////////////////////////////////////////////////////////
/**
* Remote Server Proxy to talk to the server-side code
*/
private FileServiceAsync fileServer = GWT.create(FileService.class);
/**
* Default Root Directory
*/
private String rootDirectoryDefault = "/usr/share/tomcat6/CraniumLibrary";
/**
* Current Root Directory
*/
private Directory rootDirectory = null;
/**
* Label displaying the current root directory
*/
private Label rootDirectoryDisplay = new Label(rootDirectoryDefault);
/**
* Label displaying the number of selected files
* <p>
* Set in: onModuleLoad
* <br>
* Updated in: updateSelected;
*/
private Label numSelectedLabel = new Label("0 File(s) Selected");
/**
* Workarea
* <p>
* Updated by a lot of functions
*/
private final VLayout workarea = new VLayout();
/**
* Last pipefile that was viewed
*/
private int lastPipefileId = -1;
/**
* Button that allows you to jump back to the last pipefile you viewed
*/
private final ToolStripButton backToLastPipefile = new ToolStripButton();
/**
* Message
* <p>
* Updated with the last message
*/
private final Label message = new Label();
/**
* Package Tree
* <p>
* Set in: treeRefresh
* <br>
* Used in: onModuleLoad
*/
private final Tree fullTree = new Tree();
/**
* Results Tree
* <p>
* Set in: treeResults
* <br>
* Used in: onModuleLoad
*/
private final Tree resultsTree = new Tree();
/**
* Tree Grid
* <p>
* Set in: onModuleLoad
* <br>
* Used in: selectionClickHandler, contextClickHandler, updateFullTree, updateResultsTree
*/
private final TreeGrid treeGrid = new TreeGrid();
/**
* True if packages is the highest level folder in fullTree,
* False if module type is the highest level folder in fullTree
* <p>
* Set in: onModuleLoad
* <br>
* Used in: selectionClickHandler, contextClickHandler, updateFullTree, updateResultsTree
*/
private boolean viewByPackage = true;
/**
* Int fileId => Pipefile pipe
* <p>
* Set in: treeRefresh
* <br>
* Used in: viewFile, editFile
*/
private final LinkedHashMap<Integer, Pipefile> pipes = new LinkedHashMap<Integer, Pipefile>();
/**
* String key => TreeNode node,
* each tree node is given a key which is either the path from the root to that node (used for folders)
* <p>
* Set in: treeRefresh
* <br>
* Used in: viewFile, editFile
*/
private final LinkedHashMap<String, TreeNode> nodes = new LinkedHashMap<String, TreeNode>();
/**
* String groupName => Group g
* <p>
* Set in viewGroups
* <br>
* Used in editGroup
*/
private final LinkedHashMap<String, Group> groups = new LinkedHashMap<String, Group>();
/**
* Pipefiles that are currently selected
* <p>
* Set in: selectionClickHandler
* <br>
* Used in: fileOperations
*/
private Pipefile[] selected = null;
/**
* Pipefiles that have been selected to be copied
* <p>
* Set in: contextClickHandler
* <br>
* Used in: contextClickHandler (a later event)
*/
private Pipefile[] toCopy = null;
/**
* Pipefiles that have been selected to be moved
* <p>
* Set in: contextClickHandler
* <br>
* Used in: contextClickHandler (a later event)
*/
private Pipefile[] toMove = null;
/**
* Set in: treeRefresh
* <br>
* Used in: fileOperations
*/
private String[] packages = null;
/**
* Returns all pipefiles related with the given record,
* Gets the pipefiles from the
*/
private ArrayList<Pipefile> getPipefiles(ListGridRecord[] records, Tree t){
ArrayList<Pipefile> ret = new ArrayList<Pipefile>();
for (ListGridRecord r : records){
int fileId = r.getAttributeAsInt("fileId");
if (fileId != -1){
Pipefile p = pipes.get(fileId);
ret.add(p);
}
else {
String key = r.getAttribute("key");
TreeNode node = nodes.get(key);
TreeNode[] children = t.getChildren(node);
ret.addAll(getPipefiles(children, t));
}
}
return ret;
}
private void updateSelected(){
ListGridRecord[] selectedRecords = treeGrid.getSelectedRecords();
Tree tree = treeGrid.getTree();
ArrayList<Pipefile> selectedList = getPipefiles(selectedRecords, tree);
selected = new Pipefile[selectedList.size()];
selected = selectedList.toArray(selected);
int numSelected = selected.length;
numSelectedLabel.setContents(numSelected + " File(s) Selected");
if (numSelected == 0){
basicInstructions();
}
else if (numSelected == 1){
viewFile(selected[0]);
} else {
fileOperations(selected);
}
}
/**
* Handler for when the selection in the treeGrid is updated
*/
private SelectionUpdatedHandler selectedPipefilesHandler = new SelectionUpdatedHandler() {
public void onSelectionUpdated(SelectionUpdatedEvent event){
updateSelected();
}
};
private NodeContextClickHandler contextClickHandler = new NodeContextClickHandler() {
public void onNodeContextClick(NodeContextClickEvent event){
TreeGrid grid = event.getViewer();
final Tree tree = grid.getData();
final TreeNode clicked = event.getNode();
updateSelected();
Menu contextMenu = new Menu();
if (tree.isFolder(clicked)){
if (clicked.getAttributeAsBoolean("moveHere") == true){
MenuItem paste = new MenuItem("Paste");
paste.setEnabled(toCopy != null || toMove != null);
contextMenu.addItem(paste);
paste.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler(){
public void onClick(MenuItemClickEvent event){
boolean copy = (toCopy != null);
Pipefile[] toPaste = copy ? toCopy : toMove;
if (copy){
copyFiles(toPaste, clicked.getName());
} else {
moveFiles(toPaste, clicked.getName());
}
}
});
contextMenu.addItem(new MenuItemSeparator());
}
}
MenuItem copy = new MenuItem("Copy");
copy.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler(){
public void onClick(MenuItemClickEvent event){
toCopy = selected;
toMove = null;
}
});
contextMenu.addItem(copy);
MenuItem move = new MenuItem("Move");
move.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler(){
public void onClick(MenuItemClickEvent event){
toCopy = null;
toMove = selected;
}
});
contextMenu.addItem(move);
MenuItem download = new MenuItem("Download");
download.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler(){
public void onClick(MenuItemClickEvent event){
downloadFiles(selected);
}
});
contextMenu.addItem(download);
MenuItem remove = new MenuItem("Remove");
remove.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler(){
public void onClick(MenuItemClickEvent event){
removeFiles(selected);
}
});
contextMenu.addItem(remove);
grid.setContextMenu(contextMenu);
}
};
////////////////////////////////////////////////////////////
// On Module Load
////////////////////////////////////////////////////////////
/**
* Entry point method (basically main function)
*/
public void onModuleLoad() {
// Header -- Title
Label title = new Label ();
title.setWidth100();
title.setAlign(Alignment.CENTER);
title.setHeight(50);
title.setContents("Loni Pipeline Server Library Manager");
title.setStyleName("title");
// Header -- ToolStrip
ToolStripButton home = new ToolStripButton("Home");
home.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
basicInstructions();
}
});
ToolStripButton importButton = new ToolStripButton("Import");
importButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
importForm();
}
});
ToolStripButton groupsButton = new ToolStripButton("Manage Groups");
groupsButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
viewGroups();
}
});
backToLastPipefile.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Pipefile p = pipes.get(lastPipefileId);
if (p != null){
viewFile(p);
} else {
backToLastPipefile.hide();
}
}
});
message.setStyleName("success");
message.setWidth100();
// Header -- Button Row
ToolStrip mainToolStrip = new ToolStrip();
mainToolStrip.addSpacer(1);
mainToolStrip.addButton(home);
mainToolStrip.addSeparator();
mainToolStrip.addButton(importButton);
mainToolStrip.addSeparator();
mainToolStrip.addButton(groupsButton);
mainToolStrip.addSeparator();
mainToolStrip.addButton(backToLastPipefile);
mainToolStrip.addFill();
mainToolStrip.addMember(message);
backToLastPipefile.hide();
// Header
VLayout header = new VLayout();
header.setHeight(75);
header.addMember(title);
header.addMember(mainToolStrip);
// Workarea
workarea.setWidth100();
workarea.setHeight100();
workarea.setPadding(10);
basicInstructions();
// Left -- Root Directory -- Label
rootDirectoryDisplay.setHeight(40);
rootDirectoryDisplay.setAlign(Alignment.CENTER);
rootDirectoryDisplay.setValign(VerticalAlignment.TOP);
rootDirectoryDisplay.setStyleName("largerFont");
// Left -- Root Directory -- Form
final TextItem rootNew = new TextItem();
rootNew.setShowTitle(false);
rootNew.setWidth(280);
final DynamicForm rootForm = new DynamicForm();
rootForm.setHeight(40);
rootForm.setAlign(Alignment.CENTER);
rootForm.setFields(rootNew);
// Left -- Search Form
final TextItem query = new TextItem();
query.setHint("Search");
query.setShowTitle(false);
query.setShowHintInField(true);
query.setWidth(280);
query.addChangedHandler(new ChangedHandler(){
public void onChanged(ChangedEvent event){
String q = query.getValueAsString();
if (q != null && q.length() >= 2){
treeGrid.setData(resultsTree);
updateResultsTree(q);
} else {
treeGrid.setData(fullTree);
}
}
});
DynamicForm searchForm = new DynamicForm();
searchForm.setFields(new FormItem[] {query});
searchForm.setWidth100();
// Left -- Tool Strip
final ToolStripButton byPackage = new ToolStripButton("View By Package");
byPackage.setDisabled(true);
final ToolStripButton byType = new ToolStripButton("View By Module Type");
byType.setDisabled(false);
byPackage.addClickHandler(new ClickHandler() {
public void onClick (ClickEvent event){
byPackage.setDisabled(true);
byType.setDisabled(false);
viewByPackage = true;
sortFullTree();
}
});
byType.addClickHandler(new ClickHandler() {
public void onClick (ClickEvent event){
byPackage.setDisabled(false);
byType.setDisabled(true);
viewByPackage = false;
sortFullTree();
}
});
ToolStrip toolStrip = new ToolStrip();
toolStrip.addSpacer(1);
toolStrip.addButton(byPackage);
toolStrip.addButton(byType);
// Left -- Tree Grid
TreeNode fullTreeRoot = new TreeNode();
fullTree.setRoot(fullTreeRoot);
fullTree.setShowRoot(false);
TreeNode resultsTreeRoot = new TreeNode();
resultsTree.setRoot(resultsTreeRoot);
resultsTree.setShowRoot(false);
treeGrid.setData(fullTree);
treeGrid.setShowConnectors(true);
treeGrid.setShowRollOver(false);
treeGrid.addSelectionUpdatedHandler(selectedPipefilesHandler);
treeGrid.addNodeContextClickHandler(contextClickHandler);
// Left -- Selected Files
numSelectedLabel.setHeight(25);
numSelectedLabel.setAlign(Alignment.CENTER);
numSelectedLabel.setStyleName("largerFont");
// Left
final VLayout left = new VLayout();
left.setShowResizeBar(true);
left.setCanDragResize(true);
left.setResizeFrom("L", "R");
left.setWidth(300);
left.setMinWidth(300);
left.setMaxWidth(600);
left.setAlign(Alignment.CENTER);
left.setPadding(10);
left.setBackgroundColor("#F5DEB3");
left.addMember(rootDirectoryDisplay);
left.addMember(searchForm);
left.addMember(toolStrip);
left.addMember(treeGrid);
left.addMember(numSelectedLabel);
left.addResizedHandler(new ResizedHandler() {
public void onResized (ResizedEvent event){
query.setWidth(left.getWidth() - 20);
rootNew.setWidth(left.getWidth() - 20);
}
});
rootDirectoryDisplay.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
rootNew.setValue(rootDirectory.absolutePath);
left.removeMember(rootDirectoryDisplay);
left.addMember(rootForm, 0);
rootForm.focusInItem(rootNew);
}
});
rootNew.addKeyUpHandler(new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
String pressed = event.getKeyName();
if (pressed.equals(KeyNames.ENTER)){
// Determine if the tree needs to be updated, set the rot directory
String newRoot = rootNew.getValueAsString();
String oldRoot = rootDirectory.absolutePath;
boolean updated = ( ! oldRoot.equals(newRoot) );
// Update the view
rootDirectoryDisplay.setContents(newRoot);
left.removeMember(rootForm);
left.addMember(rootDirectoryDisplay, 0);
// Get the directory
if (updated){
getDirectory(newRoot);
basicInstructions();
}
}
}
});
// Main
HLayout main = new HLayout();
main.setWidth100();
main.addMember(left);
main.addMember(workarea);
VLayout layout = new VLayout();
layout.setHeight100();
layout.setWidth100();
layout.addMember(header);
layout.addMember(main);
layout.draw();
// Tree Initialization
getDirectory(rootDirectoryDefault);
}
////////////////////////////////////////////////////////////
// Private Function - Calls to Server
////////////////////////////////////////////////////////////
/**
* Makes the RPC to getDirectory
*/
private void getDirectory(final String absolutePath){
fileServer.getDirectory(absolutePath, new AsyncCallback<Directory>() {
public void onFailure(Throwable caught) {
error("Failed to retrieve directory: " + caught.getMessage());
}
public void onSuccess(Directory result) {
if (result != null){
// Set and display the rootDirectory
rootDirectory = result;
rootDirectoryDisplay.setContents(rootDirectory.absolutePath);
// Update the files and groups
updateFullTree(null);
getGroups(false);
}
else {
// Ask for new root directory
Dialog dialog = new Dialog();
dialog.setWidth(300);
dialog.setShowCloseButton(false);
dialog.setShowModalMask(true);
dialog.setButtons(Dialog.OK);
SC.askforValue(
"Invalid Root Directory",
"Root directory does not exist or is not a directory",
absolutePath,
new ValueCallback(){
public void execute(String value) {
getDirectory(value);
}
},
dialog
);
}
}
});
}
/**
* Makes the RPC to getFiles
*/
private void getFiles(final int[] filesToSelect){
pipes.clear();
fileServer.getFiles(rootDirectory, new AsyncCallback<Pipefile[]>() {
public void onFailure(Throwable caught) {
error("Failed to retrieve files: " + caught.getMessage());
}
public void onSuccess(Pipefile[] result) {
if (result != null) {
// Set pipes and packages
LinkedHashSet<String> packageNames = new LinkedHashSet<String>();
for (Pipefile p : result){
pipes.put(p.fileId, p);
packageNames.add(p.packageName);
}
packages = new String[packageNames.size()];
packages = packageNames.toArray(packages);
// Update lastPipefile
if ( !pipes.containsKey(lastPipefileId) ){
backToLastPipefile.hide();
}
// Update the tree
sortFullTree();
selectFiles(filesToSelect);
}
else {
SC.say(rootDirectory.absolutePath + " contains no pipefiles");
}
}
}
);
}
/**
* Makes the RPC to getSearchResults
*/
private void getSearchResults(String query){
fileServer.getSearchResults(rootDirectory, query, new AsyncCallback<Pipefile[]>() {
public void onFailure(Throwable caught) {
error("Failed to retrieve search results: "+ caught.getMessage());
}
public void onSuccess(Pipefile[] result) {
// Clear the ResultsTree
resultsTree.removeList(resultsTree.getDescendants());
if (result != null){
for (Pipefile p : result){
if (pipes.containsKey(p.fileId) == false){
pipes.put(p.fileId, p);
}
TreeNode pipe = new TreeNode(p.name);
pipe.setAttribute("fileId", p.fileId);
pipe.setAttribute("viewable", true);
resultsTree.add(pipe, resultsTree.getRoot());
}
}
}
});
}
/**
* Makes the RPC to updateFile
*/
private void updateFile(final Pipefile pipe){
fileServer.updateFile(rootDirectory, pipe, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
error("Failed to update file: " + caught.getMessage());
}
public void onSuccess(Void result){
success("Successfully updated " + pipe.name);
updateFullTree( new int[] { pipe.fileId } );
getGroups(false);
basicInstructions();
}
});
}
/**
* Makes the RPC to removeFiles, after confirmation
*/
private void removeFiles(final Pipefile[] selected){
SC.confirm(
"Confirm Remove",
"Please confirm that you want to remove the "
+ selected.length + " selected file(s)",
new BooleanCallback(){
public void execute(Boolean value) {
if (value){
fileServer.removeFiles(rootDirectory, selected, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
error("Failed to remove file(s): " + caught.getMessage());
}
public void onSuccess(Void result){
success("Successfully removed " + selected.length + " file(s).");
updateFullTree(null);
basicInstructions();
}
});
}
}
}
);
}
/**
* Makes the RPC to copyFiles
*/
private void copyFiles(final Pipefile[] selected, final String packageName){
fileServer.copyFiles(rootDirectory, selected, packageName, new AsyncCallback<int[]>() {
public void onFailure(Throwable caught) {
error("Failed to copy file(s): " + caught.getMessage());
}
public void onSuccess(int[] result){
success("Successfully copied " + selected.length + " file(s) to " + packageName + ".");
updateFullTree(result);
basicInstructions();
}
});
}
/**
* Makes the RPC to moveFiles, after confirmation
*/
private void moveFiles(final Pipefile[] selected, final String packageName){
SC.confirm(
"Confirm Move",
"Please confirm that you want to move the " +
selected.length + " selected file(s) to " + packageName,
new BooleanCallback(){
public void execute(Boolean value) {
if (value){
fileServer.moveFiles(rootDirectory, selected, packageName, new AsyncCallback<int[]>() {
public void onFailure(Throwable caught) {
error("Failed to move file(s): " + caught.getMessage());
}
public void onSuccess(int[] result){
success("Successfully moved " + selected.length + " file(s) to " + packageName + ".");
updateFullTree(result);
basicInstructions();
}
});
}
}
}
);
}
/**
* Makes the RPC to getGroups
*/
private void getGroups(final boolean view){
groups.clear();
fileServer.getGroups(rootDirectory, new AsyncCallback<Group[]>() {
public void onFailure(Throwable caught) {
error("Failed to retrieve groups: " + caught.getMessage());
}
public void onSuccess(Group[] result) {
if (result != null){
for(Group g : result){
groups.put(g.name, g);
}
}
if (view){
viewGroups();
}
}
});
}
/**
* Makes the RPC to updateGroup
*/
private void updateGroup(final Group group){
fileServer.updateGroup(rootDirectory, group, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
error("Failed to update group: " + caught.getMessage());
}
public void onSuccess(Void result) {
getGroups(true);
updateFullTree(null);
success("Successfully updated " + group.name + ".");
}
});
}
/**
* Makes the RPC to removeGroups
*/
private void removeGroups(final Group[] groups){
SC.confirm(
"Confirm Remove",
"Please confirm that you want to remove the " +
groups.length + " selected groups(s). <br/>" +
"All references to this group will be removed",
new BooleanCallback(){
public void execute(Boolean value) {
if (value){
fileServer.removeGroups(rootDirectory, groups, new AsyncCallback<Void>(){
public void onFailure(Throwable caught) {
error("Failed to remove groups: "+ caught.getMessage());
}
public void onSuccess(Void result) {
getGroups(true);
updateFullTree(null);
success("Successfully removed " + groups.length + " groups(s).");
}
});
}
}
}
);
}
/**
* Makes the HTTP request to download
*/
private void downloadFiles(Pipefile[] selected){
int length = selected.length;
String url = "serverlibrarymanager/download?n=" + length;
for(int i = 0; i < length; i++){
String filename = selected[i].absolutePath;
url += "&filename_" + i + "=" + URL.encode(filename);
}
Window.open(url, "downloadWindow", "");
}
////////////////////////////////////////////////////////////
// Private Functions - Tree
////////////////////////////////////////////////////////////
private void selectFiles(int[] filesToSelect){
if (filesToSelect == null){
return;
}
Record[] records = new Record[filesToSelect.length];
int index = 0;
for (int fileId : filesToSelect){
Pipefile pipe = pipes.get(fileId);
String key = pipe.packageName + " > " + pipe.type + " > " + pipe.name;
TreeNode node = nodes.get(key);
TreeNode typeFolder = fullTree.getParent(node);
TreeNode packageFolder = fullTree.getParent(typeFolder);
fullTree.openFolder(packageFolder);
fullTree.openFolder(typeFolder);
records[index] = node;
index++;
}
treeGrid.selectRecords(records);
}
private void sortFullTree(){
// Clear the map
nodes.clear();
// Clear the full tree
fullTree.removeList(fullTree.getDescendants());
for (Pipefile p : pipes.values()){
String primaryName, secondaryName;
if (viewByPackage) {
primaryName = p.packageName;
secondaryName = p.type;
}
else {
primaryName = p.type;
secondaryName = p.packageName;
}
String primaryKey = primaryName;
String secondaryKey = primaryName + " > " + secondaryName;
// Primary Node
TreeNode primaryNode;
if (nodes.containsKey(primaryKey)){
primaryNode = nodes.get(primaryKey);
} else {
primaryNode = new TreeNode(primaryName);
primaryNode.setAttribute("fileId", -1);
primaryNode.setAttribute("key", primaryKey);
primaryNode.setAttribute("viewable", false);
primaryNode.setAttribute("moveHere", viewByPackage);
fullTree.add(primaryNode, fullTree.getRoot());
nodes.put(primaryKey, primaryNode);
}
// Secondary Node
TreeNode secondaryNode;
if (nodes.containsKey(secondaryKey)){
secondaryNode = nodes.get(secondaryKey);
} else {
secondaryNode = new TreeNode(secondaryName);
secondaryNode.setAttribute("fileId", -1);
secondaryNode.setAttribute("key", secondaryKey);
secondaryNode.setAttribute("viewable", false);
secondaryNode.setAttribute("moveHere", !viewByPackage);
fullTree.add(secondaryNode, primaryNode);
nodes.put(secondaryKey, secondaryNode);
}
// Pipefile node
String pipeKey = secondaryKey + " > " + p.name;
TreeNode pipeNode = new TreeNode(p.name);
pipeNode.setAttribute("fileId", p.fileId);
pipeNode.setAttribute("key", secondaryKey + " > " + p.name);
pipeNode.setAttribute("viewable", true);
fullTree.add(pipeNode, secondaryNode);
nodes.put(pipeKey, pipeNode);
}
}
/**
* Updates Package Tree and Module Tree based on the rootDirectory
* Ensure tree is displayed
*/
private void updateFullTree(int[] filesToSelect){
// Clear the selection
treeGrid.deselectAllRecords();
updateSelected();
fullTree.removeList(fullTree.getDescendants());
treeGrid.setData(fullTree);
getFiles(filesToSelect);
}
/**
* Updates ResultsTree based on the query
* Ensure results are displayed
*/
private void updateResultsTree(final String query){
// Clear the selection
treeGrid.deselectAllRecords();
updateSelected();
treeGrid.setData(resultsTree);
getSearchResults(query);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - File Operations
////////////////////////////////////////////////////////////
/**
* Adds file operations (download, remove, copy, move) to the workarea
*/
private void fileOperationsActions(final Pipefile[] pipefiles){
// Title
Label workareaTitle = new Label("File Operations");
workareaTitle.setHeight(20);
workareaTitle.setStyleName("workarea-title");
workarea.addMember(workareaTitle);
// Actions
final ComboBoxItem combo = new ComboBoxItem();
combo.setTitle("To Package");
combo.setValueMap(packages);
DynamicForm form = new DynamicForm();
form.setItems(combo);
Button remove = new Button("Remove");
Button download = new Button("Download");
Button copy = new Button("Copy");
Button move = new Button("Move");
remove.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
removeFiles(pipefiles);
}
});
download.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
downloadFiles(pipefiles);
}
});
copy.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
String value = combo.getValueAsString();
if (value == null || value.equals("")){
SC.say("Please specify a package");
} else {
copyFiles(pipefiles, value);
}
}
});
move.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
String value = combo.getValueAsString();
if (value == null || value.equals("")){
SC.say("Please specify a package");
} else {
moveFiles(pipefiles, value);
}
}
});
HLayout copyMoveButtons = new HLayout(10);
copyMoveButtons.setAlign(Alignment.CENTER);
copyMoveButtons.addMember(copy);
copyMoveButtons.addMember(move);
VLayout copyMoveLayout = new VLayout(5);
copyMoveLayout.setPadding(5);
copyMoveLayout.setWidth(250);
copyMoveLayout.setHeight(80);
copyMoveLayout.setShowEdges(true);
copyMoveLayout.setDefaultLayoutAlign(Alignment.CENTER);
copyMoveLayout.addMember(copyMoveButtons);
copyMoveLayout.addMember(form);
VLayout downloadLayout = new VLayout();
downloadLayout.setPadding(5);
downloadLayout.setWidth(110);
downloadLayout.setHeight(30);
downloadLayout.setShowEdges(true);
downloadLayout.addMember(download);
VLayout removeLayout = new VLayout();
removeLayout.setPadding(5);
removeLayout.setWidth(110);
removeLayout.setHeight(30);
removeLayout.setShowEdges(true);
removeLayout.addMember(remove);
final HLayout actions = new HLayout(10);
actions.setHeight(100);
actions.addMember(downloadLayout);
actions.addMember(removeLayout);
actions.addMember(copyMoveLayout);
workarea.addMember(actions);
}
/**
* Adds a list of the selected files to the workarea
*/
private void fileOperationsSelectedFiles(final Pipefile[] pipefiles){
// Title
Label selectedTitle = new Label("Selected Files (" + pipefiles.length + ")");
selectedTitle.setHeight(20);
selectedTitle.setStyleName("workarea-title");
workarea.addMember(selectedTitle);
// Selected Files
ListGrid grid = new ListGrid();
grid.setWidth(600);
ListGridField nField = new ListGridField("name", "Name");
ListGridField pField = new ListGridField("packageName", "Package");
ListGridField tField = new ListGridField("type", "Type");
grid.setFields(nField, pField, tField);
ListGridRecord[] records = new ListGridRecord[pipefiles.length];
for(int i = 0; i < pipefiles.length; i++){
Pipefile pipe = pipefiles[i];
ListGridRecord record = new ListGridRecord();
record.setAttribute("name", pipe.name);
record.setAttribute("packageName", pipe.packageName);
record.setAttribute("type", pipe.type);
record.setAttribute("fileId", pipe.fileId);
records[i] = record;
}
grid.setData(records);
grid.addRecordClickHandler(new RecordClickHandler(){
public void onRecordClick(RecordClickEvent event) {
Record clicked = event.getRecord();
int fileId = clicked.getAttributeAsInt("fileId");
Pipefile pipe = pipes.get(fileId);
selected = new Pipefile[] { pipe };
//when single file is selected from the workarea's list,
//remaining items will get deselected
treeGrid.deselectAllRecords();
viewFile(pipe);
}
});
workarea.addMember(grid);
}
/**
* Sets workarea to file Operations (download, remove, copy, move)
* and a list of the selected files
*/
private void fileOperations(final Pipefile[] pipefiles){
clearWorkarea();
fileOperationsActions(pipefiles);
fileOperationsSelectedFiles(pipefiles);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - View File
////////////////////////////////////////////////////////////
private String loopFound = "<b>LOOP IN GROUP DEPENDENCIES</b>";
private String groupHint = "Comma separated list<br/>" +
"Group syntax = " + GroupSyntax.start + "groupName" + GroupSyntax.end +
"<br/>Groups expanded below";
private String expandGroupsRecursive(String originalGroup, String list, String base){
String ret = "";
String[] agents = list.split(",");
for(String agent : agents){
// Trim whitespace
agent = agent.trim();
if (GroupSyntax.isGroup(agent)){
String group = GroupSyntax.agentToGroupname(agent);
if (group.equals(originalGroup)){
ret += base + loopFound + "<br/>";
return ret;
}
else if (groups.containsKey(group)){
Group g = groups.get(group);
ret += base + group + " = " + g.users + "<br/>";
ret += expandGroupsRecursive(originalGroup, g.users, base + " ");
}
else {
ret += base + group + " is undefined" + "<br/>";;
}
}
}
return ret;
}
/**
* Updates a static text item with the groups expanded
*/
private boolean expandGroups(String groupName, String agentList, StaticTextItem info){
String msg = expandGroupsRecursive(groupName, agentList, "");
info.setValue(msg);
return msg.contains(loopFound);
}
/**
* Sets the workarea with file operations and a form to edit
*/
private void viewFile(final Pipefile pipe){
clearWorkarea();
lastPipefileId = pipe.fileId;
backToLastPipefile.hide();
// File Operations
fileOperationsActions(new Pipefile[] {pipe});
// Title
Label editFileTitle = new Label("Edit File");
editFileTitle.setHeight(40);
editFileTitle.setStyleName("workarea-title");
workarea.addMember(editFileTitle);
// Edit File
final DynamicForm form = new DynamicForm();
form.setCanEdit(true);
form.setPadding(10);
form.setStyleName("edit-form");
int width = 400;
TextItem name = new TextItem();
name.setTitle("Name");
name.setName("name");
name.setWidth(width);
TextItem packageName = new TextItem();
packageName.setTitle("Package");
packageName.setName("package");
packageName.setWidth(width);
StaticTextItem type = new StaticTextItem();
type.setTitle("Type");
type.setName("type");
TextAreaItem description = new TextAreaItem();
description.setTitle("Description");
description.setName("description");
description.setWidth(width);
TextItem tags = new TextItem();
tags.setTitle("Tags");
tags.setName("tags");
tags.setWidth(width);
tags.setHint("Comma separated list");
SelectItem formatType = new SelectItem();
formatType.setTitle("Value Format Type");
formatType.setType("comboBox");
formatType.setName("formatType");
final String str="String", dir="Directory", file="File", num="Number";
formatType.setValueMap(str, dir, file, num);
TextAreaItem values = new TextAreaItem();
values.setTitle("Values");
values.setName("values");
values.setWidth(width);
values.setHint("Newline separated list<br/>");
final TextItem valuesPrefix = new TextItem();
valuesPrefix.setTitle("Values Prefix");
valuesPrefix.setName("valuesPrefix");
valuesPrefix.setWidth(width);
TextItem location = new TextItem();
location.setTitle("Location");
location.setName("location");
location.setWidth(width);
TextItem locationPrefix = new TextItem();
locationPrefix.setTitle("Location Prefix");
locationPrefix.setName("locationPrefix");
locationPrefix.setWidth(width);
TextItem uri = new TextItem();
uri.setTitle("URI");
uri.setName("uri");
uri.setWidth(width);
final TextAreaItem access = new TextAreaItem();
access.setTitle("Access");
access.setName("access");
access.setWidth(width);
access.setHeight(50);
access.setHint(groupHint);
final StaticTextItem accessInfo = new StaticTextItem();
accessInfo.setTitle("Access Groups Expanded");
formatType.addChangedHandler(new ChangedHandler(){
public void onChanged(ChangedEvent event){
if(form.getValueAsString("formatType").equals(num)){
valuesPrefix.disable();
}
else
valuesPrefix.enable();
}
});
access.addChangedHandler(new ChangedHandler(){
public void onChanged(ChangedEvent event){
expandGroups("", access.getValueAsString(), accessInfo);
}
});
form.setFields(name, packageName, type, description, tags, locationPrefix,
location, uri, valuesPrefix, values, formatType, access, accessInfo);
// Set the value of the fields
form.setValue("name", pipe.name);
form.setValue("package", pipe.packageName);
if(pipe.type.equals("Modules"))
form.setValue("type", "Module");
else if(pipe.type.equals("Groups"))
form.setValue("type", "Group");
else
form.setValue("type", pipe.type);
form.setValue("description", pipe.description);
form.setValue("tags",pipe.tags);
form.setValue("access", pipe.access);
expandGroups("", access.getValueAsString(), accessInfo);
if(pipe.type.equals("Data")){
String valString = "";
pipe.valuesPrefix = "";
RegExp split = RegExp.compile("\n", "m");
SplitResult vals = split.split(pipe.values);
RegExp re = RegExp.compile("((.*/)*)(.*)");
for (int j = 0; j<vals.length(); j++){
MatchResult m = re.exec(vals.get(j));
if(m != null && m.getGroup(0) !=null && m.getGroup(0).length()>0){
//check if group is null before assigning
if(m.getGroup(3) != null)
valString += m.getGroup(3) + "\n";
if(j==0){
if(m.getGroup(2) != null)
pipe.valuesPrefix = m.getGroup(2);
}else{
if(m.getGroup(2) == null || !pipe.valuesPrefix.equals(m.getGroup(2))){
pipe.valuesPrefix = "";
}
}
}
if(pipe.valuesPrefix.equals(""))
valString = pipe.values;
}
form.setValue("formatType", pipe.formatType);
if(pipe.formatType.equals(file) || pipe.formatType.equals(dir) || pipe.formatType.equals(str))
form.setValue("valuesPrefix", pipe.valuesPrefix);
else
valuesPrefix.disable();
form.setValue("values", valString);
}
else{
form.hideItem("values");
form.hideItem("valuesPrefix");
form.hideItem("formatType");
}
if(pipe.type.equals("Modules")){
String loc = "";
pipe.locationPrefix = "";
RegExp re = RegExp.compile("(.*://.*/)(.*)");
MatchResult m = re.exec(pipe.location);
if(m != null){
pipe.locationPrefix = m.getGroup(1);
loc = m.getGroup(2);
}
else{
pipe.locationPrefix = "";
loc = "";
}
form.setValue("locationPrefix", pipe.locationPrefix);
form.setValue("location", loc);
} else {
form.hideItem("locationPrefix");
form.hideItem("location");
}
if(pipe.type.equals("Modules") || pipe.type.equals("Groups")){
form.setValue("uri", pipe.uri);
}
else {
form.hideItem("uri");
}
// Update Button
Button update = new Button("Update");
update.addClickHandler( new ClickHandler() {
public void onClick(ClickEvent event) {
String newName = form.getValueAsString("name");
pipe.nameUpdated = ( ! pipe.name.equals(newName) );
String newPackageName = form.getValueAsString("package");
pipe.packageUpdated = ( ! pipe.packageName.equals(newPackageName));
pipe.name = newName;
pipe.packageName = newPackageName;
// pipe.type is not editable
pipe.description = form.getValueAsString("description");
pipe.tags = form.getValueAsString("tags");
pipe.access = form.getValueAsString("access");
if(pipe.type.equals("Data")){
String valString = "";
if(form.getValueAsString("formatType").equals(num)){
valString = form.getValueAsString("values");
}
else{ //append prefix
pipe.valuesPrefix = form.getValueAsString("valuesPrefix");
if(pipe.valuesPrefix == null)
pipe.valuesPrefix = "";
RegExp split = RegExp.compile("\n", "m");
SplitResult vals = split.split(form.getValueAsString("values"));
for (int j = 0; j<vals.length(); j++){
if(vals.get(j).length()==0)
continue;
valString += pipe.valuesPrefix + vals.get(j) + "\n";
}
}
pipe.values = valString;
pipe.formatType = form.getValueAsString("formatType");
}
if (pipe.type.equals("Modules")){
pipe.locationPrefix = form.getValueAsString("locationPrefix");
pipe.location = pipe.locationPrefix + form.getValueAsString("location");
}
if (pipe.type.equals("Modules") || pipe.type.equals("Groups")){
pipe.uri = form.getValueAsString("uri");
}
updateFile(pipe);
}
});
Button cancel = new Button("Cancel");
cancel.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
basicInstructions();
}
});
HLayout buttonRow = new HLayout(10);
buttonRow.addMember(update);
buttonRow.addMember(cancel);
workarea.addMember(form);
workarea.addMember(buttonRow);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - Groups
////////////////////////////////////////////////////////////
/**
* Sets workarea to a list of the groups
*/
private void viewGroups(){
clearWorkarea();
int width = 600;
// Title
Label title = new Label("Manage Groups");
title.setHeight(30);
title.setStyleName("workarea-title");
// Description
Label description = new Label(
"Double click a group to edit it " +
"or mark the checkboxes of groups you want to delete then click \"Remove Selected Groups\"<br/>" +
"Groups without a checkbox are in use and cannot be deleted. More info can be found in the edit screen."
);
description.setHeight(50);
description.setStyleName("workarea-description");
// Group Grid
ListGridField nField = new ListGridField("name", "Name");
ListGridField uField = new ListGridField("users", "Users");
final ListGrid grid = new ListGrid();
grid.setFields(nField, uField);
grid.setWidth(width);
grid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
Collection<Group> groupsCollection = groups.values();
ListGridRecord[] records = new ListGridRecord[groupsCollection.size()];
int i = 0;
for(Group group : groupsCollection){
ListGridRecord record = new ListGridRecord();
record.setAttribute("name", group.name);
record.setAttribute("users", group.users);
records[i++] = record;
}
grid.setData(records);
grid.addRecordDoubleClickHandler(new RecordDoubleClickHandler(){
public void onRecordDoubleClick(RecordDoubleClickEvent event){
Record r = event.getRecord();
String groupName = r.getAttribute("name");
Group g = groups.get(groupName);
editGroup(g);
}
});
// ToolStrip
Label total = new Label(records.length + " groups");
ToolStripButton newGroup = new ToolStripButton();
newGroup.setIcon("[SKIN]/actions/add.png");
newGroup.setPrompt("Add New Group");
newGroup.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
Group newGroup = new Group();
editGroup(newGroup);
}
});
ToolStripButton removeGroups = new ToolStripButton();
removeGroups.setIcon("[SKIN]/actions/remove.png");
removeGroups.setPrompt("Remove Selected Groups");
removeGroups.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
ListGridRecord[] selected = grid.getSelectedRecords();
if (selected != null && selected.length > 0){
final Group[] toRemove = new Group[selected.length];
int i = 0;
for(ListGridRecord r : selected){
String name = r.getAttribute("name");
toRemove[i++] = groups.get(name);
}
removeGroups(toRemove);
}
}
});
ToolStrip bottom = new ToolStrip();
bottom.setWidth100();
bottom.addMember(total);
bottom.addFill();
bottom.addButton(newGroup);
bottom.addButton(removeGroups);
grid.setGridComponents(new Object[] {
ListGridComponent.HEADER,
ListGridComponent.BODY,
bottom
});
workarea.addMember(title);
workarea.addMember(description);
workarea.addMember(grid);
}
/**
* Sets workarea to a form to edit a group
*/
private void editGroup(final Group g){
clearWorkarea();
final boolean newGroup = (g.groupId == -1);
int width = 400;
// Title
Label title = new Label(newGroup ? "New Group" : "Edit Group");
title.setHeight(30);
title.setStyleName("workarea-title");
// Form for editing
final TextItem name = new TextItem("Name");
name.setValue(g.name);
name.setWidth(width);
final TextAreaItem agents = new TextAreaItem("Agents");
agents.setValue(g.users);
agents.setWidth(width);
agents.setHeight(50);
agents.setHint(groupHint);
final StaticTextItem agentsInfo = new StaticTextItem();
agentsInfo.setTitle("Agent Groups Expanded");
agents.addChangedHandler(new ChangedHandler(){
public void onChanged(ChangedEvent event){
expandGroups(name.getValueAsString(), agents.getValueAsString(), agentsInfo);
}
});
DynamicForm form = new DynamicForm();
form.setFields(name, agents, agentsInfo);
form.setPadding(10);
expandGroups(name.getValueAsString(), agents.getValueAsString(), agentsInfo);
Button update = new Button("Update");
update.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
String nameValue = name.getValueAsString();
String usersValue = agents.getValueAsString();
boolean loop = expandGroups(g.name, usersValue, agentsInfo);
if (nameValue == null || nameValue.equals("")){
SC.say("Name cannot be blank");
}
else if (newGroup && groups.containsKey(nameValue)){
SC.say("Name (" + g.name + ") is already in use. Please choose another name.");
}
else if (loop){
SC.say("Loop in group dependencies. Please remove this loop.");
}
else {
g.name = nameValue;
g.users = usersValue;
updateGroup(g);
}
}
});
Button cancel = new Button("Cancel");
cancel.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
viewGroups();
}
});
HLayout buttonRow = new HLayout(10);
buttonRow.addMember(update);
buttonRow.addMember(cancel);
workarea.addMember(title);
workarea.addMember(form);
workarea.addMember(buttonRow);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - Import
////////////////////////////////////////////////////////////
/**
* Sets workarea to an import form
*/
private void importForm(){
clearWorkarea();
// Title
Label title = new Label("Import File(s)");
title.setHeight(30);
title.setStyleName("workarea-title");
// Uses GWT form components so we can submit in the background
Grid grid = new Grid(4,3);
final FormPanel uploadForm = new FormPanel();
uploadForm.setWidget(grid);
uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART);
uploadForm.setMethod(FormPanel.METHOD_POST);
uploadForm.setAction(GWT.getModuleBaseURL()+"upload");
// Package Name
Label packageLabel = new Label("Package");
packageLabel.setHeight(30);
final TextBox packageName = new TextBox();
packageName.setName("packageName");
packageName.setWidth("300px");
Label packageDescription = new Label (
"Set package to put all uploaded files into that package.<br/>" +
"If empty all files will be placed in the package specified in the file"
);
packageDescription.setHeight(30);
packageDescription.setWidth(500);
packageDescription.setStyleName("workarea-description");
grid.setWidget(0, 0, packageLabel);
grid.setWidget(0, 1, packageName);
grid.setWidget(0, 2, packageDescription);
// Upload local file
Label uploadLabel = new Label("Upload Local Files");
uploadLabel.setHeight(40);
FileUpload fileItem = new FileUpload();
fileItem.setName("theMostUniqueName");
Scheduler.get().scheduleDeferred(new Command(){
@Override
public void execute(){
enableUpload(); //FROM :: http://forums.smartclient.com/showthread.php?t=16007
}
});
Label uploadDescription = new Label (
"Select local files to upload. Accepts \".pipe\" files only. All other files are discarded."
);
uploadDescription.setHeight(30);
uploadDescription.setWidth(500);
uploadDescription.setStyleName("workarea-description");
grid.setWidget(1, 0, uploadLabel);
grid.setWidget(1, 1, fileItem);
grid.setWidget(1, 2, uploadDescription);
// Upload URLs
Label urlLabel = new Label("Upload From URLs");
urlLabel.setHeight(40);
final TextArea urls = new TextArea();
urls.setName("urls");
urls.setWidth("300px");
urls.setHeight("100px");
Label urlDescription = new Label (
"Enter a newline seperated list of urls."
);
urlDescription.setHeight(40);
urlDescription.setWidth(400);
urlDescription.setStyleName("workarea-description");
grid.setWidget(2, 0, urlLabel);
grid.setWidget(2, 1, urls);
grid.setWidget(2, 2, urlDescription);
Button uploadButton = new Button("Send");
uploadButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
uploadForm.submit();
}
});
grid.setWidget(3, 0, uploadButton);
uploadForm.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
public void onSubmitComplete(SubmitCompleteEvent event) {
if( event.getResults().length() == 0) {
success("Successfully uploaded files");
}
else {
error("Failed to upload files: " + event.getResults());
}
updateFullTree(null);
basicInstructions();
}
});
// Root Directory
Hidden hRoot = new Hidden();
hRoot.setName("root");
hRoot.setValue(rootDirectory.absolutePath);
grid.setWidget(3, 1, hRoot);
workarea.addMember(title);
workarea.addMember(uploadForm);
}
// FROM :: http://forums.smartclient.com/showthread.php?t=16007
// Allows making multiple selection of files
private native void enableUpload() /*-{
var newAttr= document.createAttribute('multiple');
newAttr.nodeValue='multiple';
$wnd.document.getElementsByName('theMostUniqueName')[0].setAttributeNode(newAttr);
}-*/;
////////////////////////////////////////////////////////////
// Private Functions - Workarea - Home
////////////////////////////////////////////////////////////
/**
* Sets workarea to the basic instructions
*/
private void basicInstructions(){
clearWorkarea();
Label root = new Label("This is your root directory. Click on it to edit.");
root.setIcon("leftarrow.jpg");
root.setIconWidth(30);
root.setHeight(40);
root.setStyleName("workarea-description");
root.setValign(VerticalAlignment.TOP);
Label search = new Label("Use this to search for files. Search must be at least 2 letters.");
search.setIcon("leftarrow.jpg");
search.setIconWidth(30);
search.setHeight(30);
search.setStyleName("workarea-description");
search.setValign(VerticalAlignment.TOP);
Label view = new Label("Use these buttons to reorder the hierarchy");
view.setIcon("leftarrow.jpg");
view.setIconWidth(30);
view.setHeight(50);
view.setStyleName("workarea-description");
view.setValign(VerticalAlignment.TOP);
workarea.addMember(root);
workarea.addMember(search);
workarea.addMember(view);
Label files = new Label(
"Select any file to view and edit its properties and perform file operations<br/>" +
"You can also select multiple files at once and perform the same operation on all of them"
);
files.setHeight(60);
files.setStyleName("workarea-description");
files.setValign(VerticalAlignment.TOP);
workarea.addMember(files);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - Messages
////////////////////////////////////////////////////////////
/**
* Prints an error message to the top of workarea
*/
private void error(String message){
SC.say(message);
}
/**
* Prints a success message to the top of workarea
*/
private void success(String msg){
message.setContents(msg);
message.animateShow(AnimationEffect.FADE);
// Clear the message after 5 seconds
new Timer() {
public void run() {
message.animateHide(AnimationEffect.FADE);
}
}.schedule(5000);
}
////////////////////////////////////////////////////////////
// Private Functions - Workarea - Clear
////////////////////////////////////////////////////////////
/**
* Clears the workarea
*/
private void clearWorkarea(){
if (pipes.containsKey(lastPipefileId)){
Pipefile pipe = pipes.get(lastPipefileId);
backToLastPipefile.setTitle("Back to " + pipe.name);
backToLastPipefile.show();
}
workarea.removeMembers(workarea.getMembers());
}
}